{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 数据集介绍\n",
    "# MNIST数据集，100k的训练数据，10k的预测数据，数据由tensorflow中的examples.tutorials.mnist读取 \n",
    "# 数据集介绍：：Yann LeCun's website\n",
    "# 由28*28的像素组成输入特征，输出特征为0-9的数字\n",
    "\n",
    "# 可调节参数：\n",
    "# --------\n",
    "# batch_size, initial_weight,二次损失函数,learning_rate,epoch_n\n",
    "# --------\n",
    "\n",
    "import tensorflow as tf\n",
    "from tensorflow.examples.tutorials.mnist import input_data\n",
    "\n",
    "mnist = input_data.read_data_sets(\"MNIST_data\", one_hot = True)\n",
    "\n",
    "# mini_batch的大小\n",
    "batch_size = 100\n",
    "batch_n = mnist.train.num_examples // batch_size\n",
    "\n",
    "# # 定义两个placeholder用来feed数据，分别代表x和y --784列和10列(one-hot)\n",
    "x = tf.placeholder(tf.float32, [None, 784])\n",
    "y = tf.placeholder(tf.float32, [None, 10])\n",
    "\n",
    "# # ----\n",
    "# # 构建多分类回归\n",
    "\n",
    "# # 定义weight和bias，初始化分别为正态随机和0.0\n",
    "initial_weight = tf.random_normal([784, 10])\n",
    "weight = tf.Variable(initial_weight)\n",
    "bias = tf.Variable(tf.zeros([10]))\n",
    "a = tf.matmul(x, weight) + bias\n",
    "y_head = tf.nn.softmax(a)\n",
    "\n",
    "# # 定义二次损失函数并依据梯度下降法进行训练 -- 这样梯度下降的train就变成了x和y的函数\n",
    "learning_rate = 0.1\n",
    "loss = tf.reduce_mean(tf.square(y - y_head))\n",
    "optimizer = tf.train.GradientDescentOptimizer(learning_rate)\n",
    "\n",
    "# tf.train.GradientDescentOptimizer\n",
    "# tf.train.AdadeltaOptimizer\n",
    "# tf.train.AdagradOptimizer\n",
    "# tf.train.AdagradDAOptimizer\n",
    "# tf.train.MomentumOptimizer\n",
    "# tf.train.AdamOptimizer\n",
    "# tf.train.FtrlOptimizer\n",
    "# tf.train.ProximalGradientDescentOptimizer\n",
    "# tf.train.ProximalAdagradOptimizer\n",
    "# tf.train.RMSPropOptimizer\n",
    "\n",
    "train = optimizer.minimize(loss)\n",
    "\n",
    "init = tf.global_variables_initializer()\n",
    "\n",
    "correct_prediction = tf.equal(tf.argmax(y, 1), tf.argmax(y_head, 1)) # tf.argmax找到x中等于1的最大的id\n",
    "correction = tf.reduce_mean(tf.cast(correct_prediction, tf.float32)) # tf.cast 转换类型，将bool转为float，从而求得准确率\n",
    "\n",
    "# 迭代500次，进行mini_batch梯度下降\n",
    "epoch_n = 500\n",
    "with tf.Session() as session:\n",
    "    session.run(init)\n",
    "    for step in range(epoch_n):\n",
    "        for batch in range(batch_n):\n",
    "            batch_x, batch_y = mnist.train.next_batch(batch_size)\n",
    "            session.run(train, feed_dict= {x: batch_x, y: batch_y}) # 此处是最小化\n",
    "        corr = session.run(correction, feed_dict= {x: mnist.test.images, y: mnist.test.labels}) # 基于测试集对准确率进行测试\n",
    "        print(\"in iteration \" + str(step) + \"the accuracy is : \" + str(corr)) # 打印准确率\n",
    "# 这里看似有问题，其实没问题，因为图没变，DAG对输入的batch依次执行梯度下降法，\n",
    "# 并执行epoch_n个周期，权重会更新epoch_n * batch_n次\n",
    "    \n",
    "\n",
    "\n",
    "\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
